#!/usr/bin/python2
# -*- coding: UTF-8 -*-
# 文件名：server.py

import socket               # 导入 socket 模块
from time import ctime
import threading             # 多线程模块
import re     # 正则表达式模块


host = socket.gethostname()  # 获取本地主机名
port = 12345                # 设置端口
Address = (host, port)
BufferSize = 1024               # 获取到的最大字节数
clients = {}    # 提供 用户名->socket 映射
chatwith = {}    # 提供通信双方映射
print "服务器host：", host


def handleMsg(sock, user):
    while True:
        data = sock.recv(BufferSize)  # 接收用户的数据
        if data == 'quit':  # 用户退出
            del clients[user]
            sock.send(data)
            sock.close()
            print '%s logout' % user
            break
        elif re.match('to:+', data) is not None:
            data = data[3:]
            if clients. has_key(data):  # 判断用户是否连接
                chatwith[sock] = clients[data]  # 将要发送的目标用户的socket以自身的socket对象为key，以目标用户socket为value保存在chatwith字典中
                chatwith[clients[data]] = sock  # 双向进行socket关联
            else:
                sock.send('用户未连接，或用户不存在' % data)  # 用户未登录，或用户不存在
        else:
            if chatwith. has_key(sock):  # 进行通信
                chatwith[sock].send("[%s] %s: %s" % (ctime(), user, data))
            else:
                sock.send('请输入你想要聊天的用户名，以[to:]开头')


serverSocket = socket.socket()         # 创建 socket 对象
serverSocket.bind(Address)        # 绑定端口
serverSocket.listen(5)                 # 等待客户端连接

while True:
    clientSocket, addr = serverSocket.accept()     # 建立客户端连接。
    print '连接地址：', addr
    username = clientSocket.recv(BufferSize)
    print "用户名：", username
    if clients. has_key(username):  # 判断用户是否存在
        clientSocket.send("用户重复登陆")
        clientSocket.close()
    else:
        clientSocket.send("Welcome!")  # 登入成功
        clients[username] = clientSocket  # username为key ，socket为值进行关联映射
        chat = threading.Thread(target=handleMsg, args=(clientSocket, username))  # 创建新线程进行处理

serverSocket.close()                # 关闭服务器连接